// Copyright (C) 2010 Razvan Constantin <razvan.constantin@rconst.net>
//
// This file is part of FileBow.
//
// FileBow is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// FileBow is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FileBow.  If not, see <http://www.gnu.org/licenses/>.

#include "logic/file-scorer.h"

#include <algorithm>
#include <string>
#include <vector>

#include "common/common.h"
#include "common/strings.h"
#include "logic/path-tree.h"

using namespace std;

namespace filebow {

////////////////////////////////////////////////////////////////////////////////
// FileScorer
////////////////////////////////////////////////////////////////////////////////

DEFINE_DEFAULTS(FileScorer);

int FileScorer::ScoreDir(const PathTree::Node* dirNode) const {
  return 0;
}

int FileScorer::ScoreFile(const PathTree::Node* fileNode) const {
  return 0;
}

////////////////////////////////////////////////////////////////////////////////
// DefaultScorer
////////////////////////////////////////////////////////////////////////////////

void DefaultScorer::SetScore(const PathTree::Node* node, int score) {
  scores[node] += score;
}

int DefaultScorer::ScoreDir(const PathTree::Node* node) const {
  return ScoreFile(node);
}

int DefaultScorer::ScoreFile(const PathTree::Node* node) const {
  NodeMap::const_iterator it = scores.find(node);
  return (it == scores.end()) ? 0 : it->second;
}

////////////////////////////////////////////////////////////////////////////////
// SimilarScorer
////////////////////////////////////////////////////////////////////////////////

SimilarScorer::SimilarScorer(const std::string& initBasename)
    : basename(initBasename) {
  // Empty.
}

int SimilarScorer::ScoreFile(const PathTree::Node* fileNode) const {
  string name = Split(fileNode->name(), '.').front();
  if (StartsWith(name, basename)) {
    return 100 + basename.length() - name.length();
  }
  return 0;
}

////////////////////////////////////////////////////////////////////////////////
// ClosestScorer
////////////////////////////////////////////////////////////////////////////////

ClosestScorer::ClosestScorer(const PathTree::Node* baseDirNode)
    : dirNode(baseDirNode) {
  // Empty.
}

int ClosestScorer::ScoreDir(const PathTree::Node* node) const {
  if (node == dirNode) {
    return 20;
  }
  //
  int parallelScore = 0;
  for(const PathTree::Node* it = dirNode;
      node && it && node->name() == it->name();
      node = node->parent(), it = it->parent()) {
    parallelScore += 10;
  }
  return parallelScore;
}

////////////////////////////////////////////////////////////////////////////////
// CompositeScorer
////////////////////////////////////////////////////////////////////////////////

CompositeScorer::CompositeScorer() {}

CompositeScorer::~CompositeScorer() {
  STLDeleteAll(&mScorers);
}

int CompositeScorer::ScoreDir(const PathTree::Node* node) const {
  int score = 0;
  for (int i=0; i < mScorers.size(); ++i) {
    score += mScorers[i]->ScoreDir(node);
  }
  return score;
}

int CompositeScorer::ScoreFile(const PathTree::Node* node) const {
  int score = 0;
  for (int i=0; i < mScorers.size(); ++i) {
    score += mScorers[i]->ScoreFile(node);
  }
  return score;
}

} // namespace filebow
